package com.geekbuy.net.native_dio_adapter

import android.app.Activity
import android.util.Log
import android.widget.Toast
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import okhttp3.*
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.IOException


/** NativeDioAdapterPlugin */
class NativeDioAdapterPlugin : FlutterPlugin, ActivityAware, MethodCallHandler {

    private lateinit var channel: MethodChannel
    private val okHttpClient = OkHttpClientManager.getInstance().okHttpClient
    private var mActivity: Activity? = null
    override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        channel = MethodChannel(flutterPluginBinding.binaryMessenger, "native_dio_adapter")
        channel.setMethodCallHandler(this)
    }

    override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {

        if (call.method == "sendRequest") {
            val options =
                GsonUtils.toObj(GsonUtils.toJson(call.arguments), RequestOptions::class.java)
            Log.e("哈哈哈",
                (options?.url ?: "") + "======" + (GsonUtils.toJson(call.arguments)
                    ?: "") + "=====" + call.method)
            val headerBuilder = Headers.Builder()
            options?.headers?.forEach { it ->
                headerBuilder.add(it.key, it.value.toString())
            }
            val headers = headerBuilder.build()

            when (options?.method) {
                "get" -> get(headers, options, result)
                "post" -> {
                    val arguments = call.arguments<Map<String, Any>>()!!
                    post(headers,
                        options,
                        result,
                        content = GsonUtils.toJson(arguments["data"]) ?: "")
                }
            }

        }
    }


    private fun get(headers: Headers, options: RequestOptions?, result: Result) {
        val urlBuilder = (options?.url ?: "").toHttpUrlOrNull()!!.newBuilder()
        options?.queryParameters?.forEach { it ->
            urlBuilder.addQueryParameter(it.key, it.value.toString())
        }
        val url: String = urlBuilder.build().toString()
        val request: Request = Request.Builder()
            .url(url)
            .headers(headers)
            .get()
            .build()
        okHttpClient.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                handlerFailure(e, result)
            }

            override fun onResponse(call: Call, response: Response) {
                handlerResponse(response, result)
            }

        })
    }

    private fun post(
        headers: Headers,
        options: RequestOptions?,
        result: Result,
        content: String = "",
    ) {
        val mediaType =
            ((headers["Content-Type"] ?: "application/json") + ";charset=utf-8").toMediaTypeOrNull()
        Log.e("Post请求参数", content + "====" + headers["Content-Type"])
        val request: Request = Request.Builder()
            .url(options?.url ?: "")
            .headers(headers)
            .post(content.toRequestBody(mediaType))
            .build()
        okHttpClient.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                handlerFailure(e, result)
            }

            override fun onResponse(call: Call, response: Response) {
                handlerResponse(response, result)
            }

        })
    }

    private fun handlerResponse(response: Response, result: Result) {
        result.success(GsonUtils.toMap(response))
    }

    private fun handlerFailure(e: IOException, result: Result) {
        Toast.makeText(mActivity, e.message, Toast.LENGTH_SHORT).show()
    }

    override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
    }

    override fun onAttachedToActivity(binding: ActivityPluginBinding) {
        mActivity = binding.activity
    }

    override fun onDetachedFromActivityForConfigChanges() {
        onDetachedFromActivity()
    }

    override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
        onAttachedToActivity(binding)
    }

    override fun onDetachedFromActivity() {
        mActivity = null
    }
}
